package com.rockymew.core.utility.http;

import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ContentDisposition {
    private static final String TOKEN = "([a-zA-Z0-9-!#$%&'*+.^_`{|}~]+)";
    private static final String QUOTED = "\"([^\"]*)\"";
    private static final Pattern TYPE = Pattern.compile(TOKEN);
    private static final Pattern PARAMETER = Pattern.compile(";\\s*(?:" + TOKEN + "=(?:" + TOKEN + "|" + QUOTED + "))?");

    private final String disposition;
    private final String type;
    private final String filename;
    private final String token;

    private ContentDisposition(String disposition, String type, String filename, String token) {
        this.disposition = disposition;
        this.type = type;
        this.filename = filename;
        this.token = token;
    }

    public static ContentDisposition parse(String string) {
        if( null == string ) return null;
        
        Matcher typeMatcher = TYPE.matcher(string);
        if (!typeMatcher.lookingAt())
            return null;
        
        String type = typeMatcher.group().toLowerCase(Locale.US);

        String filename = null;
        String token = null;
        
        Matcher parameter = PARAMETER.matcher(string);
        for (int s = typeMatcher.end(); s < string.length(); s = parameter.end()) {
            parameter.region(s, string.length());
            if (!parameter.lookingAt())
                return null; // This is not a well-formed media type.

            String name = parameter.group(1);
            if (name.equalsIgnoreCase("filename")) {
                filename = parameter.group(2) != null ? parameter.group(2) // Value
                                                                           // is
                                                                           // a
                                                                           // token.
                        : parameter.group(3); // Value is a quoted string.
            } else if (name.equals(type)) {
                token = parameter.group(2) != null ? parameter.group(2) // Value
                                                                        // is a
                                                                        // token.
                        : parameter.group(3); // Value is a quoted string.
            } else {
                continue;
            }
        }

        return new ContentDisposition(string, type, filename, token);
    }
    
    public String getType() {
        return type;
    }

    public String getFilename() {
        return filename;
    }

    public String getToken() {
        return token;
    }

    @Override
    public String toString() {
        return disposition;
    }
}
